package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
)

type RsaCrypto struct {
	publicKey  []byte
	privateKey []byte
}

func NewRsaCrypto(pubKey, privKey string) *RsaCrypto {
	return &RsaCrypto{
		publicKey:  []byte(fmt.Sprintf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----", pubKey)),
		privateKey: []byte(fmt.Sprintf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----", privKey)),
	}
}

// 公钥加密
func (rc *RsaCrypto) PublicKeyEncrypt(data []byte) ([]byte, error) {
	block, _ := pem.Decode(rc.publicKey)
	if block == nil {
		return nil, errors.New("public key error")
	}
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	pub := pubInterface.(*rsa.PublicKey)
	return rsa.EncryptPKCS1v15(rand.Reader, pub, data)
}

// 私钥解密
func (rc *RsaCrypto) PrivateKeyDecrypt(encrypted []byte) ([]byte, error) {
	block, _ := pem.Decode(rc.privateKey)
	if block == nil {
		return nil, errors.New("private key error!")
	}
	privInterface, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	priv := privInterface.(*rsa.PrivateKey)
	return rsa.DecryptPKCS1v15(rand.Reader, priv, encrypted)
}

func main() {
	javaPrivate := "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKMuTmht3fshAvcag18GsUzF6GuyurtVzbq/zy90KZ5vnMc/6wEj0pYkOA/Vy283pyTcztVhuK5316m5fcezyPmKWWVLZHuiV1Wr/x+KTHCGffKB4vOMFHauivkBCObo3yxAFUmFhfmDtizOA+NgCL8vj27T70RtIIuY/A5SmHXVAgMBAAECgYAIgO8Cl6kf/2QnaukKMG/YY57dT+rVvN6z+u9p1mid0kyuAHl3bX25p8kJIDfSA6kw7VXU/lrwspuZQ2qX19li/F0jaBA/0KUmsrulRinVu39Y+e7Ng88f3mOYDP6ivj31J6RLyKS8qGDa+rNw1RVGydAzCH4fpoiSNfkT0GRM6QJBANW0qh2CQw2sgFxYziZMYcD0OdwOVyOXo6ZC09aQ3tZysOtl0ueBPGpz3Sr42ELpsU5fr+9j0Wj9kMD6IeVhzXkCQQDDedD1R135UdBQ/eypWMwD9AN45BzIr4UhntHcvgY+okWUGn12MhDMnRO4+W0Byn4ah70xGju93aAfZu0yfoA9AkA+X5SnODXJ7+cnDOReWTzOzHl2uNjGEqQ5Cpg5r97aSG9KxVVhLF8t0tNij27PWNXfQh5fiIq+UgPFzzvFb15BAkBAK1snSdhVoj/qdpEcPqQqoA4Lv4abctMXaFWoS1EteoOwzMlm5aSSJvZ0gJ0CO4EOIIVA+0WlXH3WESnIq7JZAkEAhbBoj/2b57pBpkmSxIcjLTGqgzhSaCjX0HbYwYYaOU3pAnHmFOk1cyhDtYmBecSejxMklj11B4HRQ1S37Y7s6A==";
	javaPublic := "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjLk5obd37IQL3GoNfBrFMxehrsrq7Vc26v88vdCmeb5zHP+sBI9KWJDgP1ctvN6ck3M7VYbiud9epuX3Hs8j5illlS2R7oldVq/8fikxwhn3ygeLzjBR2ror5AQjm6N8sQBVJhYX5g7YszgPjYAi/L49u0+9EbSCLmPwOUph11QIDAQAB";
	//javaPublic := "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4MQl5WrGNUzIqRV1qSI5p9xJl7JydIjMuhN9MBJKBron3CJDsklTGYF59n8Fx8H15k0DyPGZ3yia9ElQwmiWyj37DFaFPs7duFnVkYObO9AopVGckmMRh6e2W2+/CkOINBJxh5nZ2eQcckszee9lq+UqgVKLohKAjH2jz3FapXQIDAQAB"
	//javaPrivate := "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALgxCXlasY1TMipFXWpIjmn3EmXsnJ0iMy6E30wEkoGuifcIkOySVMZgXn2fwXHwfXmTQPI8ZnfKJr0SVDCaJbKPfsMVoU+zt24WdWRg5s70CilUZySYxGHp7Zbb78KQ4g0EnGHmdnZ5BxySzN572Wr5SqBUouiEoCMfaPPcVqldAgMBAAECgYAAkmponY76lN0Ng4ygNVx32MQOW/c6h64oAVKeLk90JqIYCcdFbMjlmswAUNwtaeVB2OK1PdnFmnOXV7S6N+hRDcbIccaSCV3rpi1e/1ZoO8qRXm+WM2WMeSU0tdkawkw8aQCnDRivuFakLjB5tDjxA+6o3i0qN8oLrF8QxGMTUwJBANlDC5yEPRsDFsGs3NcF8u3cOxtTpV2CR+QBtz+H61sTVnq+tWhhGy/XrquZZ1fVvaeW5et3g74kRtBhTJbIQ68CQQDZCH2IMM6+f3xRnOjFH6tXkb0oJjHi4qiPcgfMcSQR9hP1WEKCMAFPBUNYOUKvd73U8P3rVGk8ZyaiYq7hHYqzAkBXVGrLbCA/xlsUWI6gY8TFNZwQnOvAjYimLsZg5BqHjltZlWTH4xiRf4m3cj8nAERuo+ohXvX2rRBF3IZzqWYDAkEAsT5/1oOVtHnE+5nbd3E/q0p4Ypuezh4xbsS/nbUgshJ3hjzIRC4UQ4aW0ywgS9DMlWUi2decAhpzsNZK38oShQJBAI/on1nQ/JY8567Mi7g5dnuE3LO1GF6LBuIbymUzPNyfPGdbuHk2CNVms3O/I/kCrHAK4z5trYdeBN+uPikUefY="
	data := "hello rsa"

	rsaCrypto := NewRsaCrypto(javaPublic, javaPrivate)

	encrypted, err := rsaCrypto.PublicKeyEncrypt([]byte(data))
	if err != nil {
		panic(err)
	}
	fmt.Println("公钥加密:", base64.StdEncoding.EncodeToString(encrypted))

	decrypted, err := rsaCrypto.PrivateKeyDecrypt(encrypted)
	if err != nil {
		panic(err)
	}
	fmt.Println("私钥解密:", string(decrypted))
}
